/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 adv_object_type_properties.h

	$Header: /heroes4/adv_object_type_properties.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( ADV_OBJECT_TYPE_PROPERTIES_H_INCLUDED )
#define ADV_OBJECT_TYPE_PROPERTIES_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <assert.h>
#include <map>
#include "string_insensitive_compare.h"

enum t_adv_object_type;

// ------------------------------------------------------------------------------
// t_adv_object_minor_subtype_properties class
// ------------------------------------------------------------------------------

class t_adv_object_minor_subtype_properties
{
public:
	// Constructor
	t_adv_object_minor_subtype_properties() {}
	t_adv_object_minor_subtype_properties( std::string const & keyword );

	// Member functions
	std::string const & get_keyword() const;

private:
	// Data members
	std::string	m_keyword;
};

inline t_adv_object_minor_subtype_properties::t_adv_object_minor_subtype_properties( std::string const & keyword )
	:	m_keyword( keyword )
{
}

inline std::string const & t_adv_object_minor_subtype_properties::get_keyword() const
{
	return m_keyword;
}

// ------------------------------------------------------------------------------
// t_adv_object_major_subtype_properties class
// ------------------------------------------------------------------------------

class t_adv_object_major_subtype_properties
{
public:
	// Types
	typedef t_adv_object_minor_subtype_properties t_subtype_properties;

	// Constructor
	t_adv_object_major_subtype_properties() {}
	explicit t_adv_object_major_subtype_properties( std::string const & keyword );
	t_adv_object_major_subtype_properties(
		std::string const &				keyword,
		int								subtype_count,
		t_subtype_properties const *	subtype_properties_array );

	// Member functions
	std::string const &				get_keyword() const;
	bool							has_subtypes() const;
	int								get_subtype_count() const;
	t_subtype_properties const &	get_subtype_properties( int subtype ) const;
	int								get_subtype_value( std::string const& keyword ) const;

private:
	typedef std::map<std::string, int, t_string_insensitive_less> t_type_map;

	// Data members
	std::string						m_keyword;
	int								m_subtype_count;
	t_type_map                      m_subtype_map;
	t_subtype_properties const *	m_subtype_properties_array;
};

inline t_adv_object_major_subtype_properties::t_adv_object_major_subtype_properties(
	std::string const & keyword )
	:	m_keyword( keyword ),
		m_subtype_count( 0 ),
		m_subtype_properties_array( 0 )
{
}


inline std::string const & t_adv_object_major_subtype_properties::get_keyword() const
{
	return m_keyword;
}

inline bool t_adv_object_major_subtype_properties::has_subtypes() const
{
	return m_subtype_count > 0;
}

inline int t_adv_object_major_subtype_properties::get_subtype_count() const
{
	return m_subtype_count;
}

inline t_adv_object_major_subtype_properties::t_subtype_properties const &
t_adv_object_major_subtype_properties::get_subtype_properties( int subtype ) const
{
	assert( subtype >= 0 && subtype < m_subtype_count );
	return m_subtype_properties_array[ subtype ];
}

// ------------------------------------------------------------------------------
// t_adv_object_type_properties class
// ------------------------------------------------------------------------------

class t_adv_object_type_properties
{
public:
	// Types
	typedef t_adv_object_major_subtype_properties t_subtype_properties;

	// Constructor
	t_adv_object_type_properties();
	explicit t_adv_object_type_properties( t_adv_object_type type, std::string const & keyword );
	t_adv_object_type_properties( t_adv_object_type type, std::string const & keyword,
		                          int subtype_count, 
								  t_subtype_properties const * subtype_properties_array );

	// Member functions
	std::string const &			 get_keyword() const;
	int							 get_subtype_count() const;
	t_subtype_properties const & get_subtype_properties( int subtype ) const;
	int                          get_subtype_value( std::string const& keyword ) const;
	t_adv_object_type			 get_type() const;
	bool						 has_subtypes() const;

private:
	typedef std::map<std::string, int, t_string_insensitive_less> t_type_map;

	// Data members
	std::string						m_keyword;
	int								m_subtype_count;
	t_type_map                      m_subtype_map;
	t_subtype_properties const *	m_subtype_properties_array;
	t_adv_object_type			    m_type;
};

inline t_adv_object_type_properties::t_adv_object_type_properties( t_adv_object_type type,
																   std::string const & keyword )
	:	m_type( type ), m_keyword( keyword ),
		m_subtype_count( 0 ),
		m_subtype_properties_array( 0 )
{
}

inline std::string const & t_adv_object_type_properties::get_keyword() const
{
	return m_keyword;
}

inline bool t_adv_object_type_properties::has_subtypes() const
{
	return m_subtype_count > 0;
}

inline int t_adv_object_type_properties::get_subtype_count() const
{
	return m_subtype_count;
}

inline t_adv_object_type_properties::t_subtype_properties const & t_adv_object_type_properties::get_subtype_properties( int subtype ) const
{
	assert( subtype >= 0 && subtype < m_subtype_count );
	return m_subtype_properties_array[ subtype ];
}

inline t_adv_object_type t_adv_object_type_properties::get_type() const
{
	return m_type;
}

t_adv_object_type_properties const & get_adv_object_type_properties( t_adv_object_type adv_object_type );

#endif // ADV_OBJECT_TYPE_PROPERTIES_H_INCLUDED